/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DCGTree;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 *
 * @author Raito
 */
public class StringParse {
    private String X;
    private List<String> formatX = new ArrayList<String>();
    
    public StringParse(String X){
        this.X = X;
    }
    
    public List<String> getFormatX() {
		return formatX;
    }
    public void setFormatX(List<String> formatX) {
            this.formatX = formatX;
    }
    
    public String formatString(){
        String [] temp = null;
        String regex = " ";
        temp = X.split(regex);
        X = "";
        for(String s : temp){
            X = X.concat(s);
        }
        return X;
    }
    
    public List<String> getToken(){
     
        char[] charater = X.toCharArray();
        String temp = "";
        for (int i = 0; i< charater.length ;i++){
            if (charater[i] == '(' || charater[i] == ')' || charater[i] == ','){
                if (!"".equals(temp)){
                    formatX.add(temp);                    
                    formatX.add(String.valueOf(charater[i]));
                }
                else{
                    formatX.add(String.valueOf(charater[i]));
                }                                   
                temp = "";
            }            
            else{
                temp += charater[i];                
            }
        }
        
        return formatX;
    }
    
    public String findParent(String node, int step){
        int countPoss = 0;
        int countNeg = 0;
        if(step == 0){
            return null;
        }
        else{
            
                countNeg = step - 1;
                if (formatX.get(countNeg).equals("(")){
                    countNeg = step - 2;
                    return formatX.get(countNeg);
                }
                
                if (formatX.get(countNeg).equals(",")){
                    countPoss = definePos(step) - 1;
                    return formatX.get(countPoss);
                }
                
        }
        
        return null;
    }
    
    public int definePos(int index)
    {
        int i;
        int countPos = 0;
        int countNeg = 1;
        for (i = index; i >=0; i--){
            if (")".equals(formatX.get(i))){
                countNeg++;
            }
            if ("(".equals(formatX.get(i))){
                countPos++;
            }
            if (Math.abs(countNeg-countPos) == 0){
                break;
            }
        }
        return i;
    }
    
   
    
    public List<String> findChild(int index){
        List<String> listPos = new ArrayList<String>();        
        int i;
        int countPos = 0;
        int countNeg = 0;
        int temp = 0;
        int pos = 0;
        int flag = 0;
        int length = formatX.size();
        
        if ("(".equals(formatX.get(index+1))&& ",".equals(formatX.get(index+3))){
            String s = "";
            for (i = index+1; i < length; i++){
                if (")".equals(formatX.get(i))){
                    countNeg++;
                }
                if ("(".equals(formatX.get(i))){
                    countPos++;
                }
                if ((countPos - countNeg) == 0)
                    return listPos;
                pos = i + 1;
                s = formatX.get(pos);
                if (!")".equals(s)&&!",".equals(s)){
                    listPos.add(String.valueOf(pos));
                }
                
            }
        }
        
        for (i = index; i < length; i++){
            if (")".equals(formatX.get(i))){
                countNeg++;
            }
            if ("(".equals(formatX.get(i))){
                countPos++;
            }
            if ((countPos - countNeg) == -1){
                return null;
            }
                       
            
            if ((countPos - countNeg) == 1 && (countPos - countNeg) != temp){
                pos = i+1;
                String s = formatX.get(pos);
                if (!")".equals(s)&&!",".equals(s)){
                    listPos.add(String.valueOf(pos));
                    flag = pos + 1;
                    s = formatX.get(flag);
                    if (")".equals(s)){
                        break;
                    }
                }
                else if (",".equals(s)){
                    pos = pos + 1;
                    s = formatX.get(pos);
                    listPos.add(String.valueOf(pos));
                }
                else if (")".equals(s)){
                    flag = i + 1;
                    s = formatX.get(flag);
                    if (")".equals(s)){
                        break;
                    }
                }
            }
            temp = (countPos - countNeg);
            
            
        }
        return listPos;
        
    }
    
    public Node parseToTree()
    {
        int index;
        Stack<Node> stack = new Stack<Node>();
        Node root = new Node(0);
        root.setValue(formatX.get(0));
        stack.add(root);
        
        while(!stack.isEmpty()){
            Node temp = new Node();
            temp = stack.pop();
            List<String> nodeChild = new ArrayList<String>();
            nodeChild = findChild(temp.getIndex());
            
            if (nodeChild != null){
                for (String s : nodeChild){
                    index = Integer.parseInt(s);
                    Node child = new Node(index);
                    child.setValue(formatX.get(index));
                    if (child.getNodeParent() == null){
                        child.setNodeParent(new Node());                    
                        child.setNodeParent(temp);
                    }
                    temp.getNodeChild().add(child);
                    stack.add(child);                        
                }
            }
            
            if (nodeChild == null)
                temp.setNodeChild(null);
            
            
        } 
        return root;
        
    }
    
   
}
